#include "Inf_HLW8032.h"

// #include "driver/gpio.h"
#include "driver/uart.h"

// #define hhh GPIO_NUM_20

#define EX_UART_NUM UART_NUM_0

#define BUF_SIZE (1024) // 串口内部接收缓冲区大小

// 电压系数
#define VOLTAGE_COEFFICIENT 1.88
// 电流系数
#define CURRENT_COEFFICIENT 0.25

// 串口接收数据缓冲区
uint8_t rx_buff[24];

// 记录HLW8032的PF寄存器溢出次数
uint16_t count_PF;

// 接收数据
static Com_State_T Inf_HLW8032_Receive(void) {
    int count = uart_read_bytes(EX_UART_NUM, rx_buff, 24, 1000);
    if (count == 24) {
        uart_flush(EX_UART_NUM); // 清空内部缓冲区
        return COM_OK;
    }
    return COM_FAILE;
}

// 校验数据
static Com_State_T Inf_HLW8032_Checkout(uint8_t *data) {
    uint8_t checknum = 0;
    for (uint8_t i = 2; i < 23; i++) {
        checknum += data[i];
    }

    if (checknum == data[23]) {
        return COM_OK;
    }
    return COM_FAILE;
}

// 计算HLW8032的PF寄存器溢出次数
static void Inf_HLW8032_ComputePF(uint8_t data) {
    static uint8_t last_status = 0;         // 记录上一次数据更新寄存器最高位的状态
    uint8_t current_status = (data & 0x80); // 当前数据更新寄存器最高位的状态

    // 翻转了则表示溢出了1次
    if (last_status != current_status) {
        count_PF++;
        last_status = current_status;
    }
}

void Inf_HLW8032_Init(void) {

    // Configure UART parameters
    uart_config_t uart_config = {
        .baud_rate = 4800,                     // 波特率：4800bps
        .data_bits = UART_DATA_8_BITS,         // 数据位：8位
        .parity = UART_PARITY_EVEN,            // 校验位：偶校验
        .stop_bits = UART_STOP_BITS_1,         // 停止位：1位
        .flow_ctrl = UART_HW_FLOWCTRL_DISABLE, // 不使用硬件流控制
        .source_clk = UART_SCLK_DEFAULT,
    };
    ESP_ERROR_CHECK(uart_param_config(EX_UART_NUM, &uart_config));

    // Install UART driver, and get the queue.
    uart_driver_install(EX_UART_NUM, BUF_SIZE, 0, 0, NULL, 0);

    uart_set_pin(EX_UART_NUM, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);
}

void Inf_HLW8032_ComputeValues(HLW8032_Parameters *value) {

    if (Inf_HLW8032_Receive() != COM_OK) {
        // MY_LOGE("数据接收失败");
        return;
    }
    if (Inf_HLW8032_Checkout(rx_buff) != COM_OK) {
        // MY_LOGE("数据校验失败");
        return;
    }

    Inf_HLW8032_ComputePF(rx_buff[20]);

    // 计算电压
    value->voltage = VOLTAGE_COEFFICIENT * ((rx_buff[2] << 16) | (rx_buff[3] << 8) | rx_buff[4]) / ((rx_buff[5] << 16) | (rx_buff[6] << 8) | rx_buff[7]);
    // 计算电流
    value->current = CURRENT_COEFFICIENT * ((rx_buff[8] << 16) | (rx_buff[9] << 8) | rx_buff[10]) / ((rx_buff[11] << 16) | (rx_buff[12] << 8) | rx_buff[13]);
    // 计算有功功率
    value->active_power = VOLTAGE_COEFFICIENT * CURRENT_COEFFICIENT * ((rx_buff[14] << 16) | (rx_buff[15] << 8) | rx_buff[16]) / ((rx_buff[17] << 16) | (rx_buff[18] << 8) | rx_buff[19]);
    // 计算视在功率
    value->apparent_power = value->voltage * value->current;
    // 计算用电量（W.h）
    // 【芯片输出脉冲数】 / 【(1/1000)度电的脉冲数量】
    value->electricity = (count_PF * 65535.0 + ((rx_buff[21] << 8) | rx_buff[22])) / (3600000000.0 / ((rx_buff[14] << 16) | (rx_buff[15] << 8) | rx_buff[16]) / VOLTAGE_COEFFICIENT / CURRENT_COEFFICIENT);
}
